package top.zhangjianyong.tools.indicator.strategy.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.zhangjianyong.tools.entity.ETFData;
import top.zhangjianyong.tools.indicator.context.IndicatorContext;
import top.zhangjianyong.tools.indicator.model.TechnicalIndicatorResult;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 均线乖离指标计算器
 * 计算价格相对于均线的乖离率
 * 支持bias_sma20、bias_ema20
 *
 * @author zhangjianyong
 * @date 2024/01/01
 */
@Component
public class BiasIndicator extends AbstractIndicator {

    private static final String INDICATOR_NAME = "BIAS";

    @Autowired
    private SMAIndicator smaIndicator;

    @Autowired
    private EMAIndicator emaIndicator;

    @Override
    public String getName() {
        return INDICATOR_NAME;
    }

    @Override
    public int getMinDataSize() {
        return 20; // 需要20日均线
    }

    @Override
    protected TechnicalIndicatorResult doCalculate(IndicatorContext context) {
        List<ETFData> dataList = context.getDataList();
        if (dataList.isEmpty()) {
            return TechnicalIndicatorResult.failure(getName(), "数据列表为空");
        }

        // 获取当前价格（最后一个数据点）
        BigDecimal currentPrice = dataList.get(dataList.size() - 1).getValue();

        TechnicalIndicatorResult result = TechnicalIndicatorResult.success(getName());

        // 计算SMA20的乖离率
        TechnicalIndicatorResult smaResult = smaIndicator.calculate(context);
        if (smaResult.isSuccess()) {
            BigDecimal sma20 = smaResult.getBigDecimalValue("sma_20");
            if (sma20 != null && sma20.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal biasSma20 = currentPrice.subtract(sma20)
                    .divide(sma20, 4, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal(100));
                result.addValue("bias_sma20", biasSma20.setScale(2, RoundingMode.HALF_UP));
            }
        }

        // 计算EMA20的乖离率
        TechnicalIndicatorResult emaResult = emaIndicator.calculate(context);
        if (emaResult.isSuccess()) {
            BigDecimal ema20 = emaResult.getBigDecimalValue("ema_20");
            if (ema20 != null && ema20.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal biasEma20 = currentPrice.subtract(ema20)
                    .divide(ema20, 4, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal(100));
                result.addValue("bias_ema20", biasEma20.setScale(2, RoundingMode.HALF_UP));
            }
        }

        return result;
    }
}

